#include "cmdpartner.h"

#include "../mainctrl.h"
#include "../cmd/dataprepare.h"
#include "commmsg.h"

CT_REGISTER_ASYNCCMD(ID_MAIN_PARTNER, CCmdPartner);

int CCmdPartner::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_PARTNER ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_PARTNER,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);

    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam); //消息解析
    if (iRet)
    {
        return AnsClients(iRet);
    }

	chSubCmd = stReq.sub_type();
    uiGID = stReq.gid();
    shResID = 0;
    if (stReq.has_res_id())
    {
        shResID = stReq.res_id();
    }

    //检查登录
    iRet = pstMainCtrl->CheckLogin(uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    stAns.set_gid((int)uiGID);
    stAns.set_sub_type(chSubCmd);

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdPartner::LogicDo(int iRet)
{
    if (iRet != 0)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, uiGID);
    ASSERT_PLAYER_PREPARED(uiGID);

    PREPARE_PLAYER_DETAIL_INFO(this, uiGID);
    ASSERT_PLAYER_DETAIL_PREPARED(uiGID);

    PREPARE_UNACT_PARTNER_INFO(this, uiGID);
    ASSERT_UNACT_PARTNER_PREPARED(uiGID);

    PREPARE_PLAYER_DETAIL_EX1_INFO(this, uiGID);
    ASSERT_PLAYER_DETAIL_EX1_INFO(uiGID);

    PREPARE_PLAYER_ONLINE_DATA(this, uiGID);

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
	{
        CT_ERROR(("no base data user(%u)", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
	}
	CPlayerBaseInfo& stPlayerBase = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBase._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
    if (iIndex < 0)
	{
        CT_ERROR(("no detail data user(%u)", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
	}
	CPlayerDetailInfo& stPlayerDetail = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stUnactPartnerInfoHash.HashFind(uiGID);
    if (iIndex < 0)
	{
        CT_ERROR(("no unact partner data user(%u)", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
	}
	CUnactPartnerInfo& stUnactPartnerInfo = pstMainCtrl->m_stUnactPartnerInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("get user detail ex1 info error, uid = %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerDetailInfoEx1& stPlayerDetailEx1Info =
        pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no online data user %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
	CPlayerOnlineData& stPlayerOnline = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

	switch (chSubCmd)
	{
	case CPartnerMgr::CMD_PARTNER_SUB_ACT:
    	iRet = pstMainCtrl->m_stPartnerMgr.PartnerGetAct(stPlayerOnline, stPlayerDetail, stPlayerBase, stAns);
		break;
	case CPartnerMgr::CMD_PARTNER_SUB_LIST:
    	iRet = pstMainCtrl->m_stPartnerMgr.PartnerGetList(stUnactPartnerInfo, *(stAns.mutable_list_partner()));
		break;
	case CPartnerMgr::CMD_PARTNER_SUB_JOIN:
    	iRet = pstMainCtrl->m_stPartnerMgr.PartnerJoin(shResID,
            CPartnerMgr::PARTNER_JOIN_TYPE_NORMAL, stPlayerBase, stPlayerDetail,
            stUnactPartnerInfo, stPlayerOnline, stPlayerDetailEx1Info, stAns);
        
        if (iRet == RET_OK)
        {
            pstMainCtrl->m_stTaskMgr.TriggerDoSomeOpt(stPlayerOnline._stUserTask, 109000 + shResID, 1);

            pstMainCtrl->m_stActMgr.TriggerGetPartner(stPlayerDetail._stSplendidAct, uiGID, shResID);
        }

		break;
	case CPartnerMgr::CMD_PARTNER_SUB_SIGN:
    	iRet = pstMainCtrl->m_stPartnerMgr.PartnerSign(shResID, stPlayerBase,
            stPlayerDetail, stPlayerOnline, stPlayerDetailEx1Info, stAns);
		break;
	case CPartnerMgr::CMD_PARTNER_SUB_LOCK:
    	iRet = pstMainCtrl->m_stPartnerMgr.PartnerLock(shResID, stPlayerBase,
            stPlayerDetail, stPlayerOnline, stPlayerDetailEx1Info, stAns);
		break;
	case CPartnerMgr::CMD_PARTNER_SUB_LEAVE:
    	iRet = pstMainCtrl->m_stPartnerMgr.PartnerLeave(shResID, stPlayerBase,
            stPlayerDetail, stUnactPartnerInfo, stPlayerOnline, stAns);
		break;
	case CPartnerMgr::CMD_PARTNER_SUB_RECALL:
    	iRet = pstMainCtrl->m_stPartnerMgr.PartnerRecall(shResID, stPlayerBase,
            stPlayerDetail, stUnactPartnerInfo, stPlayerOnline,
            stPlayerDetailEx1Info, stAns);
        
        if (iRet == RET_OK)
        {
            pstMainCtrl->m_stTaskMgr.TriggerDoSomeOpt(stPlayerOnline._stUserTask, 109000 + shResID, 1);
        }
		break;
    case CPartnerMgr::CMD_PARTNER_SUB_GET_CONDITION:
        {
            iRet = pstMainCtrl->m_stPartnerMgr.PartnerGetJoinWay(stPlayerBase,
                stPlayerOnline, stAns);
        }
		break;
	default:
		iRet = ERROR_MAIN_SUB_CMD;
		break;
	}

    if (iRet)
    {
        CT_TRACE(("user(gid=%u) deal partner(resid=%d) op(sub=%d) error(%d)",uiGID,shResID,chSubCmd,iRet));
        return AnsClients(iRet);
    }

	if (chSubCmd == CPartnerMgr::CMD_PARTNER_SUB_JOIN ||
		chSubCmd == CPartnerMgr::CMD_PARTNER_SUB_SIGN)
	{
    	//保存数据 base info
    	CVarObjectKey stKey;
    	stKey.m_chDataType = DT_PLAYER_BASE_INFO;
    	stKey.m_u64ID = uiGID;
    	pstMainCtrl->UpdateData(stKey, stPlayerBase, VOP_UPDATE);
	}

	if (chSubCmd == CPartnerMgr::CMD_PARTNER_SUB_JOIN ||
		chSubCmd == CPartnerMgr::CMD_PARTNER_SUB_SIGN ||
		chSubCmd == CPartnerMgr::CMD_PARTNER_SUB_LOCK ||
		chSubCmd == CPartnerMgr::CMD_PARTNER_SUB_LEAVE ||
		chSubCmd == CPartnerMgr::CMD_PARTNER_SUB_RECALL)
	{
    	//保存数据 detail info
    	CVarObjectKey stKey;
    	stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
    	stKey.m_u64ID = uiGID;
    	pstMainCtrl->UpdateData(stKey, stPlayerDetail, VOP_UPDATE);

	}

	if (chSubCmd == CPartnerMgr::CMD_PARTNER_SUB_LEAVE ||
		chSubCmd == CPartnerMgr::CMD_PARTNER_SUB_RECALL)
	{
    	//保存数据 unact partner
    	CVarObjectKey stKey;
    	stKey.m_chDataType = DT_PLAYER_UNACT_PARTNER;
    	stKey.m_u64ID = uiGID;
    	pstMainCtrl->UpdateData(stKey, stUnactPartnerInfo, VOP_UPDATE);
	}

    return AnsClients(RET_OK);
}

int CCmdPartner::AnsClients(int iRet)
{
    pstMainCtrl->m_stEncodeBuf.Clear();

    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);

    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf, true))
    {
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}

